home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Linux / Kubuntu 8.10 / kubuntu-8.10-desktop-i386.iso / casper / filesystem.squashfs / usr / lib / python2.5 / idlelib / PyShell.pyc (.txt) < prev    next >
Python Compiled Bytecode  |  2008-10-29  |  46KB  |  1,496 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.5)
  3.  
  4. import os
  5. import os.path as os
  6. import sys
  7. import string
  8. import getopt
  9. import re
  10. import socket
  11. import time
  12. import threading
  13. import traceback
  14. import types
  15. import macosxSupport
  16. import linecache
  17. from code import InteractiveInterpreter
  18.  
  19. try:
  20.     from Tkinter import *
  21. except ImportError:
  22.     print >>sys.__stderr__, "** IDLE can't import Tkinter.  Your Python may not be configured for Tk. **"
  23.     sys.exit(1)
  24.  
  25. import tkMessageBox
  26. from EditorWindow import EditorWindow, fixwordbreaks
  27. from FileList import FileList
  28. from ColorDelegator import ColorDelegator
  29. from UndoDelegator import UndoDelegator
  30. from OutputWindow import OutputWindow
  31. from configHandler import idleConf
  32. import idlever
  33. import rpc
  34. import Debugger
  35. import RemoteDebugger
  36. IDENTCHARS = string.ascii_letters + string.digits + '_'
  37. LOCALHOST = '127.0.0.1'
  38.  
  39. try:
  40.     from signal import SIGTERM
  41. except ImportError:
  42.     SIGTERM = 15
  43.  
  44. warning_stream = sys.__stderr__
  45.  
  46. try:
  47.     import warnings
  48. except ImportError:
  49.     pass
  50.  
  51.  
  52. def idle_showwarning(message, category, filename, lineno):
  53.     file = warning_stream
  54.     
  55.     try:
  56.         file.write(warnings.formatwarning(message, category, filename, lineno))
  57.     except IOError:
  58.         pass
  59.  
  60.  
  61. warnings.showwarning = idle_showwarning
  62.  
  63. def idle_formatwarning(message, category, filename, lineno):
  64.     '''Format warnings the IDLE way'''
  65.     s = '\nWarning (from warnings module):\n'
  66.     s += '  File "%s", line %s\n' % (filename, lineno)
  67.     line = linecache.getline(filename, lineno).strip()
  68.     if line:
  69.         s += '    %s\n' % line
  70.     
  71.     s += '%s: %s\n>>> ' % (category.__name__, message)
  72.     return s
  73.  
  74. warnings.formatwarning = idle_formatwarning
  75.  
  76. def extended_linecache_checkcache(filename = None, orig_checkcache = linecache.checkcache):
  77.     '''Extend linecache.checkcache to preserve the <pyshell#...> entries
  78.  
  79.     Rather than repeating the linecache code, patch it to save the
  80.     <pyshell#...> entries, call the original linecache.checkcache()
  81.     (which destroys them), and then restore the saved entries.
  82.  
  83.     orig_checkcache is bound at definition time to the original
  84.     method, allowing it to be patched.
  85.  
  86.     '''
  87.     cache = linecache.cache
  88.     save = { }
  89.     for filename in cache.keys():
  90.         if filename[:1] + filename[-1:] == '<>':
  91.             save[filename] = cache[filename]
  92.             continue
  93.     
  94.     orig_checkcache()
  95.     cache.update(save)
  96.  
  97. linecache.checkcache = extended_linecache_checkcache
  98.  
  99. class PyShellEditorWindow(EditorWindow):
  100.     '''Regular text edit window in IDLE, supports breakpoints'''
  101.     
  102.     def __init__(self, *args):
  103.         self.breakpoints = []
  104.         EditorWindow.__init__(self, *args)
  105.         self.text.bind('<<set-breakpoint-here>>', self.set_breakpoint_here)
  106.         self.text.bind('<<clear-breakpoint-here>>', self.clear_breakpoint_here)
  107.         self.text.bind('<<open-python-shell>>', self.flist.open_shell)
  108.         self.breakpointPath = os.path.join(idleConf.GetUserCfgDir(), 'breakpoints.lst')
  109.         if self.io.filename:
  110.             self.restore_file_breaks()
  111.         
  112.         
  113.         def filename_changed_hook(old_hook = self.io.filename_change_hook, self = self):
  114.             self.restore_file_breaks()
  115.             old_hook()
  116.  
  117.         self.io.set_filename_change_hook(filename_changed_hook)
  118.  
  119.     rmenu_specs = [
  120.         ('Set Breakpoint', '<<set-breakpoint-here>>'),
  121.         ('Clear Breakpoint', '<<clear-breakpoint-here>>')]
  122.     
  123.     def set_breakpoint(self, lineno):
  124.         text = self.text
  125.         filename = self.io.filename
  126.         text.tag_add('BREAK', '%d.0' % lineno, '%d.0' % (lineno + 1))
  127.         
  128.         try:
  129.             i = self.breakpoints.index(lineno)
  130.         except ValueError:
  131.             self.breakpoints.append(lineno)
  132.  
  133.         
  134.         try:
  135.             debug = self.flist.pyshell.interp.debugger
  136.             debug.set_breakpoint_here(filename, lineno)
  137.         except:
  138.             pass
  139.  
  140.  
  141.     
  142.     def set_breakpoint_here(self, event = None):
  143.         text = self.text
  144.         filename = self.io.filename
  145.         if not filename:
  146.             text.bell()
  147.             return None
  148.         
  149.         lineno = int(float(text.index('insert')))
  150.         self.set_breakpoint(lineno)
  151.  
  152.     
  153.     def clear_breakpoint_here(self, event = None):
  154.         text = self.text
  155.         filename = self.io.filename
  156.         if not filename:
  157.             text.bell()
  158.             return None
  159.         
  160.         lineno = int(float(text.index('insert')))
  161.         
  162.         try:
  163.             self.breakpoints.remove(lineno)
  164.         except:
  165.             pass
  166.  
  167.         text.tag_remove('BREAK', 'insert linestart', 'insert lineend +1char')
  168.         
  169.         try:
  170.             debug = self.flist.pyshell.interp.debugger
  171.             debug.clear_breakpoint_here(filename, lineno)
  172.         except:
  173.             pass
  174.  
  175.  
  176.     
  177.     def clear_file_breaks(self):
  178.         if self.breakpoints:
  179.             text = self.text
  180.             filename = self.io.filename
  181.             if not filename:
  182.                 text.bell()
  183.                 return None
  184.             
  185.             self.breakpoints = []
  186.             text.tag_remove('BREAK', '1.0', END)
  187.             
  188.             try:
  189.                 debug = self.flist.pyshell.interp.debugger
  190.                 debug.clear_file_breaks(filename)
  191.  
  192.         
  193.  
  194.     
  195.     def store_file_breaks(self):
  196.         '''Save breakpoints when file is saved'''
  197.         breaks = self.breakpoints
  198.         filename = self.io.filename
  199.         
  200.         try:
  201.             lines = open(self.breakpointPath, 'r').readlines()
  202.         except IOError:
  203.             lines = []
  204.  
  205.         new_file = open(self.breakpointPath, 'w')
  206.         for line in lines:
  207.             if not line.startswith(filename + '='):
  208.                 new_file.write(line)
  209.                 continue
  210.         
  211.         self.update_breakpoints()
  212.         breaks = self.breakpoints
  213.         if breaks:
  214.             new_file.write(filename + '=' + str(breaks) + '\n')
  215.         
  216.         new_file.close()
  217.  
  218.     
  219.     def restore_file_breaks(self):
  220.         self.text.update()
  221.         filename = self.io.filename
  222.         if filename is None:
  223.             return None
  224.         
  225.         if os.path.isfile(self.breakpointPath):
  226.             lines = open(self.breakpointPath, 'r').readlines()
  227.             for line in lines:
  228.                 if line.startswith(filename + '='):
  229.                     breakpoint_linenumbers = eval(line[len(filename) + 1:])
  230.                     for breakpoint_linenumber in breakpoint_linenumbers:
  231.                         self.set_breakpoint(breakpoint_linenumber)
  232.                     
  233.             
  234.         
  235.  
  236.     
  237.     def update_breakpoints(self):
  238.         '''Retrieves all the breakpoints in the current window'''
  239.         text = self.text
  240.         ranges = text.tag_ranges('BREAK')
  241.         linenumber_list = self.ranges_to_linenumbers(ranges)
  242.         self.breakpoints = linenumber_list
  243.  
  244.     
  245.     def ranges_to_linenumbers(self, ranges):
  246.         lines = []
  247.         for index in range(0, len(ranges), 2):
  248.             lineno = int(float(ranges[index]))
  249.             end = int(float(ranges[index + 1]))
  250.             while lineno < end:
  251.                 lines.append(lineno)
  252.                 lineno += 1
  253.         
  254.         return lines
  255.  
  256.     
  257.     def _close(self):
  258.         '''Extend base method - clear breaks when module is closed'''
  259.         self.clear_file_breaks()
  260.         EditorWindow._close(self)
  261.  
  262.  
  263.  
  264. class PyShellFileList(FileList):
  265.     '''Extend base class: IDLE supports a shell and breakpoints'''
  266.     EditorWindow = PyShellEditorWindow
  267.     pyshell = None
  268.     
  269.     def open_shell(self, event = None):
  270.         if self.pyshell:
  271.             self.pyshell.top.wakeup()
  272.         else:
  273.             self.pyshell = PyShell(self)
  274.             if self.pyshell:
  275.                 if not self.pyshell.begin():
  276.                     return None
  277.                 
  278.             
  279.         return self.pyshell
  280.  
  281.  
  282.  
  283. class ModifiedColorDelegator(ColorDelegator):
  284.     '''Extend base class: colorizer for the shell window itself'''
  285.     
  286.     def __init__(self):
  287.         ColorDelegator.__init__(self)
  288.         self.LoadTagDefs()
  289.  
  290.     
  291.     def recolorize_main(self):
  292.         self.tag_remove('TODO', '1.0', 'iomark')
  293.         self.tag_add('SYNC', '1.0', 'iomark')
  294.         ColorDelegator.recolorize_main(self)
  295.  
  296.     
  297.     def LoadTagDefs(self):
  298.         ColorDelegator.LoadTagDefs(self)
  299.         theme = idleConf.GetOption('main', 'Theme', 'name')
  300.         self.tagdefs.update({
  301.             'stdin': {
  302.                 'background': None,
  303.                 'foreground': None },
  304.             'stdout': idleConf.GetHighlight(theme, 'stdout'),
  305.             'stderr': idleConf.GetHighlight(theme, 'stderr'),
  306.             'console': idleConf.GetHighlight(theme, 'console'),
  307.             None: idleConf.GetHighlight(theme, 'normal') })
  308.  
  309.  
  310.  
  311. class ModifiedUndoDelegator(UndoDelegator):
  312.     '''Extend base class: forbid insert/delete before the I/O mark'''
  313.     
  314.     def insert(self, index, chars, tags = None):
  315.         
  316.         try:
  317.             if self.delegate.compare(index, '<', 'iomark'):
  318.                 self.delegate.bell()
  319.                 return None
  320.         except TclError:
  321.             pass
  322.  
  323.         UndoDelegator.insert(self, index, chars, tags)
  324.  
  325.     
  326.     def delete(self, index1, index2 = None):
  327.         
  328.         try:
  329.             if self.delegate.compare(index1, '<', 'iomark'):
  330.                 self.delegate.bell()
  331.                 return None
  332.         except TclError:
  333.             pass
  334.  
  335.         UndoDelegator.delete(self, index1, index2)
  336.  
  337.  
  338.  
  339. class MyRPCClient(rpc.RPCClient):
  340.     
  341.     def handle_EOF(self):
  342.         '''Override the base class - just re-raise EOFError'''
  343.         raise EOFError
  344.  
  345.  
  346.  
  347. class ModifiedInterpreter(InteractiveInterpreter):
  348.     
  349.     def __init__(self, tkconsole):
  350.         self.tkconsole = tkconsole
  351.         locals = sys.modules['__main__'].__dict__
  352.         InteractiveInterpreter.__init__(self, locals = locals)
  353.         self.save_warnings_filters = None
  354.         self.restarting = False
  355.         self.subprocess_arglist = self.build_subprocess_arglist()
  356.  
  357.     port = 8833
  358.     rpcclt = None
  359.     rpcpid = None
  360.     
  361.     def spawn_subprocess(self):
  362.         args = self.subprocess_arglist
  363.         self.rpcpid = os.spawnv(os.P_NOWAIT, sys.executable, args)
  364.  
  365.     
  366.     def build_subprocess_arglist(self):
  367.         w = [ '-W' + s for s in sys.warnoptions ]
  368.         del_exitf = idleConf.GetOption('main', 'General', 'delete-exitfunc', default = False, type = 'bool')
  369.         if __name__ == 'idlelib.PyShell':
  370.             command = "__import__('idlelib.run').run.main(%r)" % (del_exitf,)
  371.         else:
  372.             command = "__import__('run').main(%r)" % (del_exitf,)
  373.         if sys.platform[:3] == 'win' and ' ' in sys.executable:
  374.             decorated_exec = '"%s"' % sys.executable
  375.         else:
  376.             decorated_exec = sys.executable
  377.         return [
  378.             decorated_exec] + w + [
  379.             '-c',
  380.             command,
  381.             str(self.port)]
  382.  
  383.     
  384.     def start_subprocess(self):
  385.         self.spawn_subprocess()
  386.         addr = (LOCALHOST, self.port)
  387.         for i in range(3):
  388.             time.sleep(i)
  389.             
  390.             try:
  391.                 self.rpcclt = MyRPCClient(addr)
  392.             continue
  393.             except socket.error:
  394.                 err = None
  395.                 continue
  396.             
  397.  
  398.         else:
  399.             return None
  400.         self.rpcclt.listening_sock.settimeout(10)
  401.         
  402.         try:
  403.             self.rpcclt.accept()
  404.         except socket.timeout:
  405.             None<EXCEPTION MATCH>socket.error
  406.             err = None<EXCEPTION MATCH>socket.error
  407.             self.display_no_subprocess_error()
  408.             return None
  409.         except:
  410.             None<EXCEPTION MATCH>socket.error
  411.  
  412.         self.rpcclt.register('stdin', self.tkconsole)
  413.         self.rpcclt.register('stdout', self.tkconsole.stdout)
  414.         self.rpcclt.register('stderr', self.tkconsole.stderr)
  415.         self.rpcclt.register('flist', self.tkconsole.flist)
  416.         self.rpcclt.register('linecache', linecache)
  417.         self.rpcclt.register('interp', self)
  418.         self.transfer_path()
  419.         self.poll_subprocess()
  420.         return self.rpcclt
  421.  
  422.     
  423.     def restart_subprocess(self):
  424.         if self.restarting:
  425.             return self.rpcclt
  426.         
  427.         self.restarting = True
  428.         debug = self.getdebugger()
  429.         if debug:
  430.             
  431.             try:
  432.                 RemoteDebugger.close_subprocess_debugger(self.rpcclt)
  433.  
  434.         
  435.         self.rpcclt.close()
  436.         self.unix_terminate()
  437.         console = self.tkconsole
  438.         was_executing = console.executing
  439.         console.executing = False
  440.         self.spawn_subprocess()
  441.         
  442.         try:
  443.             self.rpcclt.accept()
  444.         except socket.timeout:
  445.             err = None
  446.             self.display_no_subprocess_error()
  447.             return None
  448.  
  449.         self.transfer_path()
  450.         console.text.delete('iomark', 'end-1c')
  451.         if was_executing:
  452.             console.write('\n')
  453.             console.showprompt()
  454.         
  455.         halfbar = ((int(console.width) - 16) // 2) * '='
  456.         console.write(halfbar + ' RESTART ' + halfbar)
  457.         console.text.mark_set('restart', 'end-1c')
  458.         console.text.mark_gravity('restart', 'left')
  459.         console.showprompt()
  460.         if debug:
  461.             gui = RemoteDebugger.restart_subprocess_debugger(self.rpcclt)
  462.             debug.load_breakpoints()
  463.         
  464.         self.restarting = False
  465.         return self.rpcclt
  466.  
  467.     
  468.     def __request_interrupt(self):
  469.         self.rpcclt.remotecall('exec', 'interrupt_the_server', (), { })
  470.  
  471.     
  472.     def interrupt_subprocess(self):
  473.         threading.Thread(target = self._ModifiedInterpreter__request_interrupt).start()
  474.  
  475.     
  476.     def kill_subprocess(self):
  477.         
  478.         try:
  479.             self.rpcclt.close()
  480.         except AttributeError:
  481.             pass
  482.  
  483.         self.unix_terminate()
  484.         self.tkconsole.executing = False
  485.         self.rpcclt = None
  486.  
  487.     
  488.     def unix_terminate(self):
  489.         '''UNIX: make sure subprocess is terminated and collect status'''
  490.         if hasattr(os, 'kill'):
  491.             
  492.             try:
  493.                 os.kill(self.rpcpid, SIGTERM)
  494.             except OSError:
  495.                 return None
  496.  
  497.             
  498.             try:
  499.                 os.waitpid(self.rpcpid, 0)
  500.             except OSError:
  501.                 return None
  502.             except:
  503.                 None<EXCEPTION MATCH>OSError
  504.             
  505.  
  506.         None<EXCEPTION MATCH>OSError
  507.  
  508.     
  509.     def transfer_path(self):
  510.         self.runcommand('if 1:\n        import sys as _sys\n        _sys.path = %r\n        del _sys\n        \n' % (sys.path,))
  511.  
  512.     active_seq = None
  513.     
  514.     def poll_subprocess(self):
  515.         clt = self.rpcclt
  516.         if clt is None:
  517.             return None
  518.         
  519.         
  520.         try:
  521.             response = clt.pollresponse(self.active_seq, wait = 0.05)
  522.         except (EOFError, IOError, KeyboardInterrupt):
  523.             if self.tkconsole.closing:
  524.                 return None
  525.             
  526.             response = None
  527.             self.restart_subprocess()
  528.  
  529.         if response:
  530.             self.tkconsole.resetoutput()
  531.             self.active_seq = None
  532.             (how, what) = response
  533.             console = self.tkconsole.console
  534.             if how == 'OK':
  535.                 if what is not None:
  536.                     print >>console, repr(what)
  537.                 
  538.             elif how == 'EXCEPTION':
  539.                 if self.tkconsole.getvar('<<toggle-jit-stack-viewer>>'):
  540.                     self.remote_stack_viewer()
  541.                 
  542.             elif how == 'ERROR':
  543.                 errmsg = 'PyShell.ModifiedInterpreter: Subprocess ERROR:\n'
  544.                 print >>sys.__stderr__, errmsg, what
  545.                 print >>console, errmsg, what
  546.             
  547.             
  548.             try:
  549.                 self.tkconsole.endexecuting()
  550.             except AttributeError:
  551.                 pass
  552.             except:
  553.                 None<EXCEPTION MATCH>AttributeError
  554.             
  555.  
  556.         None<EXCEPTION MATCH>AttributeError
  557.         if not self.tkconsole.closing:
  558.             self.tkconsole.text.after(self.tkconsole.pollinterval, self.poll_subprocess)
  559.         
  560.  
  561.     debugger = None
  562.     
  563.     def setdebugger(self, debugger):
  564.         self.debugger = debugger
  565.  
  566.     
  567.     def getdebugger(self):
  568.         return self.debugger
  569.  
  570.     
  571.     def open_remote_stack_viewer(self):
  572.         '''Initiate the remote stack viewer from a separate thread.
  573.  
  574.         This method is called from the subprocess, and by returning from this
  575.         method we allow the subprocess to unblock.  After a bit the shell
  576.         requests the subprocess to open the remote stack viewer which returns a
  577.         static object looking at the last exceptiopn.  It is queried through
  578.         the RPC mechanism.
  579.  
  580.         '''
  581.         self.tkconsole.text.after(300, self.remote_stack_viewer)
  582.  
  583.     
  584.     def remote_stack_viewer(self):
  585.         import RemoteObjectBrowser as RemoteObjectBrowser
  586.         oid = self.rpcclt.remotequeue('exec', 'stackviewer', ('flist',), { })
  587.         if oid is None:
  588.             self.tkconsole.root.bell()
  589.             return None
  590.         
  591.         item = RemoteObjectBrowser.StubObjectTreeItem(self.rpcclt, oid)
  592.         ScrolledCanvas = ScrolledCanvas
  593.         TreeNode = TreeNode
  594.         import TreeWidget
  595.         top = Toplevel(self.tkconsole.root)
  596.         theme = idleConf.GetOption('main', 'Theme', 'name')
  597.         background = idleConf.GetHighlight(theme, 'normal')['background']
  598.         sc = ScrolledCanvas(top, bg = background, highlightthickness = 0)
  599.         sc.frame.pack(expand = 1, fill = 'both')
  600.         node = TreeNode(sc.canvas, None, item)
  601.         node.expand()
  602.  
  603.     gid = 0
  604.     
  605.     def execsource(self, source):
  606.         '''Like runsource() but assumes complete exec source'''
  607.         filename = self.stuffsource(source)
  608.         self.execfile(filename, source)
  609.  
  610.     
  611.     def execfile(self, filename, source = None):
  612.         '''Execute an existing file'''
  613.         if source is None:
  614.             source = open(filename, 'r').read()
  615.         
  616.         
  617.         try:
  618.             code = compile(source, filename, 'exec')
  619.         except (OverflowError, SyntaxError):
  620.             self.tkconsole.resetoutput()
  621.             tkerr = self.tkconsole.stderr
  622.             print >>tkerr, '*** Error in script or command!\n'
  623.             print >>tkerr, 'Traceback (most recent call last):'
  624.             InteractiveInterpreter.showsyntaxerror(self, filename)
  625.             self.tkconsole.showprompt()
  626.  
  627.         self.runcode(code)
  628.  
  629.     
  630.     def runsource(self, source):
  631.         '''Extend base class method: Stuff the source in the line cache first'''
  632.         filename = self.stuffsource(source)
  633.         self.more = 0
  634.         self.save_warnings_filters = warnings.filters[:]
  635.         warnings.filterwarnings(action = 'error', category = SyntaxWarning)
  636.         if isinstance(source, types.UnicodeType):
  637.             import IOBinding as IOBinding
  638.             
  639.             try:
  640.                 source = source.encode(IOBinding.encoding)
  641.             except UnicodeError:
  642.                 self.tkconsole.resetoutput()
  643.                 self.write('Unsupported characters in input\n')
  644.                 return None
  645.             except:
  646.                 None<EXCEPTION MATCH>UnicodeError
  647.             
  648.  
  649.         None<EXCEPTION MATCH>UnicodeError
  650.         
  651.         try:
  652.             return InteractiveInterpreter.runsource(self, source, filename)
  653.         finally:
  654.             if self.save_warnings_filters is not None:
  655.                 warnings.filters[:] = self.save_warnings_filters
  656.                 self.save_warnings_filters = None
  657.             
  658.  
  659.  
  660.     
  661.     def stuffsource(self, source):
  662.         '''Stuff source in the filename cache'''
  663.         filename = '<pyshell#%d>' % self.gid
  664.         self.gid = self.gid + 1
  665.         lines = source.split('\n')
  666.         linecache.cache[filename] = (len(source) + 1, 0, lines, filename)
  667.         return filename
  668.  
  669.     
  670.     def prepend_syspath(self, filename):
  671.         """Prepend sys.path with file's directory if not already included"""
  672.         self.runcommand('if 1:\n            _filename = %r\n            import sys as _sys\n            from os.path import dirname as _dirname\n            _dir = _dirname(_filename)\n            if not _dir in _sys.path:\n                _sys.path.insert(0, _dir)\n            del _filename, _sys, _dirname, _dir\n            \n' % (filename,))
  673.  
  674.     
  675.     def showsyntaxerror(self, filename = None):
  676.         '''Extend base class method: Add Colorizing
  677.  
  678.         Color the offending position instead of printing it and pointing at it
  679.         with a caret.
  680.  
  681.         '''
  682.         text = self.tkconsole.text
  683.         stuff = self.unpackerror()
  684.         if stuff:
  685.             (msg, lineno, offset, line) = stuff
  686.             if lineno == 1:
  687.                 pos = 'iomark + %d chars' % (offset - 1)
  688.             else:
  689.                 pos = 'iomark linestart + %d lines + %d chars' % (lineno - 1, offset - 1)
  690.             text.tag_add('ERROR', pos)
  691.             text.see(pos)
  692.             char = text.get(pos)
  693.             if char and char in IDENTCHARS:
  694.                 text.tag_add('ERROR', pos + ' wordstart', pos)
  695.             
  696.             self.tkconsole.resetoutput()
  697.             self.write('SyntaxError: %s\n' % str(msg))
  698.         else:
  699.             self.tkconsole.resetoutput()
  700.             InteractiveInterpreter.showsyntaxerror(self, filename)
  701.         self.tkconsole.showprompt()
  702.  
  703.     
  704.     def unpackerror(self):
  705.         (type, value, tb) = sys.exc_info()
  706.         ok = type is SyntaxError
  707.         if ok:
  708.             
  709.             try:
  710.                 (dummy_filename, lineno, offset, line) = (msg,)
  711.                 if not offset:
  712.                     offset = 0
  713.             ok = 0
  714.  
  715.         
  716.         if ok:
  717.             return (msg, lineno, offset, line)
  718.         else:
  719.             return None
  720.  
  721.     
  722.     def showtraceback(self):
  723.         '''Extend base class method to reset output properly'''
  724.         self.tkconsole.resetoutput()
  725.         self.checklinecache()
  726.         InteractiveInterpreter.showtraceback(self)
  727.         if self.tkconsole.getvar('<<toggle-jit-stack-viewer>>'):
  728.             self.tkconsole.open_stack_viewer()
  729.         
  730.  
  731.     
  732.     def checklinecache(self):
  733.         c = linecache.cache
  734.         for key in c.keys():
  735.             if key[:1] + key[-1:] != '<>':
  736.                 del c[key]
  737.                 continue
  738.         
  739.  
  740.     
  741.     def runcommand(self, code):
  742.         '''Run the code without invoking the debugger'''
  743.         if self.tkconsole.executing:
  744.             self.display_executing_dialog()
  745.             return 0
  746.         
  747.         if self.rpcclt:
  748.             self.rpcclt.remotequeue('exec', 'runcode', (code,), { })
  749.         else:
  750.             exec code in self.locals
  751.         return 1
  752.  
  753.     
  754.     def runcode(self, code):
  755.         '''Override base class method'''
  756.         if self.tkconsole.executing:
  757.             self.interp.restart_subprocess()
  758.         
  759.         self.checklinecache()
  760.         if self.save_warnings_filters is not None:
  761.             warnings.filters[:] = self.save_warnings_filters
  762.             self.save_warnings_filters = None
  763.         
  764.         debugger = self.debugger
  765.         
  766.         try:
  767.             self.tkconsole.beginexecuting()
  768.             
  769.             try:
  770.                 if not debugger and self.rpcclt is not None:
  771.                     self.active_seq = self.rpcclt.asyncqueue('exec', 'runcode', (code,), { })
  772.                 elif debugger:
  773.                     debugger.run(code, self.locals)
  774.                 else:
  775.                     exec code in self.locals
  776.             except SystemExit:
  777.                 if not self.tkconsole.closing:
  778.                     if tkMessageBox.askyesno('Exit?', 'Do you want to exit altogether?', default = 'yes', master = self.tkconsole.text):
  779.                         raise 
  780.                     else:
  781.                         self.showtraceback()
  782.                 else:
  783.                     raise 
  784.             except:
  785.                 self.tkconsole.closing
  786.                 if use_subprocess:
  787.                     print >>self.tkconsole.stderr, 'IDLE internal error in runcode()'
  788.                 
  789.                 self.showtraceback()
  790.                 if use_subprocess:
  791.                     self.tkconsole.endexecuting()
  792.                 
  793.  
  794.         finally:
  795.             if not use_subprocess:
  796.                 
  797.                 try:
  798.                     self.tkconsole.endexecuting()
  799.                 except AttributeError:
  800.                     pass
  801.                 except:
  802.                     None<EXCEPTION MATCH>AttributeError
  803.                 
  804.  
  805.  
  806.  
  807.     
  808.     def write(self, s):
  809.         '''Override base class method'''
  810.         self.tkconsole.stderr.write(s)
  811.  
  812.     
  813.     def display_port_binding_error(self):
  814.         tkMessageBox.showerror('Port Binding Error', "IDLE can't bind TCP/IP port 8833, which is necessary to communicate with its Python execution server.  Either no networking is installed on this computer or another process (another IDLE?) is using the port.  Run IDLE with the -n command line switch to start without a subprocess and refer to Help/IDLE Help 'Running without a subprocess' for further details.", master = self.tkconsole.text)
  815.  
  816.     
  817.     def display_no_subprocess_error(self):
  818.         tkMessageBox.showerror('Subprocess Startup Error', "IDLE's subprocess didn't make connection.  Either IDLE can't start a subprocess or personal firewall software is blocking the connection.", master = self.tkconsole.text)
  819.  
  820.     
  821.     def display_executing_dialog(self):
  822.         tkMessageBox.showerror('Already executing', 'The Python Shell window is already executing a command; please wait until it is finished.', master = self.tkconsole.text)
  823.  
  824.  
  825.  
  826. class PyShell(OutputWindow):
  827.     shell_title = 'Python Shell'
  828.     ColorDelegator = ModifiedColorDelegator
  829.     UndoDelegator = ModifiedUndoDelegator
  830.     menu_specs = [
  831.         ('file', '_File'),
  832.         ('edit', '_Edit'),
  833.         ('debug', '_Debug'),
  834.         ('options', '_Options'),
  835.         ('windows', '_Windows'),
  836.         ('help', '_Help')]
  837.     if macosxSupport.runningAsOSXApp():
  838.         del menu_specs[-3]
  839.         menu_specs[-2] = ('windows', '_Window')
  840.     
  841.     from IdleHistory import History
  842.     
  843.     def __init__(self, flist = None):
  844.         if use_subprocess:
  845.             ms = self.menu_specs
  846.             if ms[2][0] != 'shell':
  847.                 ms.insert(2, ('shell', 'She_ll'))
  848.             
  849.         
  850.         self.interp = ModifiedInterpreter(self)
  851.         if flist is None:
  852.             root = Tk()
  853.             fixwordbreaks(root)
  854.             root.withdraw()
  855.             flist = PyShellFileList(root)
  856.         
  857.         OutputWindow.__init__(self, flist, None, None)
  858.         self.usetabs = True
  859.         self.indentwidth = 8
  860.         self.context_use_ps1 = True
  861.         text = self.text
  862.         text.configure(wrap = 'char')
  863.         text.bind('<<newline-and-indent>>', self.enter_callback)
  864.         text.bind('<<plain-newline-and-indent>>', self.linefeed_callback)
  865.         text.bind('<<interrupt-execution>>', self.cancel_callback)
  866.         text.bind('<<beginning-of-line>>', self.home_callback)
  867.         text.bind('<<end-of-file>>', self.eof_callback)
  868.         text.bind('<<open-stack-viewer>>', self.open_stack_viewer)
  869.         text.bind('<<toggle-debugger>>', self.toggle_debugger)
  870.         text.bind('<<toggle-jit-stack-viewer>>', self.toggle_jit_stack_viewer)
  871.         if use_subprocess:
  872.             text.bind('<<view-restart>>', self.view_restart_mark)
  873.             text.bind('<<restart-shell>>', self.restart_shell)
  874.         
  875.         self.save_stdout = sys.stdout
  876.         self.save_stderr = sys.stderr
  877.         self.save_stdin = sys.stdin
  878.         import IOBinding
  879.         self.stdout = PseudoFile(self, 'stdout', IOBinding.encoding)
  880.         self.stderr = PseudoFile(self, 'stderr', IOBinding.encoding)
  881.         self.console = PseudoFile(self, 'console', IOBinding.encoding)
  882.         if not use_subprocess:
  883.             sys.stdout = self.stdout
  884.             sys.stderr = self.stderr
  885.             sys.stdin = self
  886.         
  887.         self.history = self.History(self.text)
  888.         self.pollinterval = 50
  889.  
  890.     
  891.     def get_standard_extension_names(self):
  892.         return idleConf.GetExtensions(shell_only = True)
  893.  
  894.     reading = False
  895.     executing = False
  896.     canceled = False
  897.     endoffile = False
  898.     closing = False
  899.     
  900.     def set_warning_stream(self, stream):
  901.         global warning_stream
  902.         warning_stream = stream
  903.  
  904.     
  905.     def get_warning_stream(self):
  906.         return warning_stream
  907.  
  908.     
  909.     def toggle_debugger(self, event = None):
  910.         if self.executing:
  911.             tkMessageBox.showerror("Don't debug now", 'You can only toggle the debugger when idle', master = self.text)
  912.             self.set_debugger_indicator()
  913.             return 'break'
  914.         else:
  915.             db = self.interp.getdebugger()
  916.             if db:
  917.                 self.close_debugger()
  918.             else:
  919.                 self.open_debugger()
  920.  
  921.     
  922.     def set_debugger_indicator(self):
  923.         db = self.interp.getdebugger()
  924.         self.setvar('<<toggle-debugger>>', not (not db))
  925.  
  926.     
  927.     def toggle_jit_stack_viewer(self, event = None):
  928.         pass
  929.  
  930.     
  931.     def close_debugger(self):
  932.         db = self.interp.getdebugger()
  933.         if db:
  934.             self.interp.setdebugger(None)
  935.             db.close()
  936.             if self.interp.rpcclt:
  937.                 RemoteDebugger.close_remote_debugger(self.interp.rpcclt)
  938.             
  939.             self.resetoutput()
  940.             self.console.write('[DEBUG OFF]\n')
  941.             sys.ps1 = '>>> '
  942.             self.showprompt()
  943.         
  944.         self.set_debugger_indicator()
  945.  
  946.     
  947.     def open_debugger(self):
  948.         if self.interp.rpcclt:
  949.             dbg_gui = RemoteDebugger.start_remote_debugger(self.interp.rpcclt, self)
  950.         else:
  951.             dbg_gui = Debugger.Debugger(self)
  952.         self.interp.setdebugger(dbg_gui)
  953.         dbg_gui.load_breakpoints()
  954.         sys.ps1 = '[DEBUG ON]\n>>> '
  955.         self.showprompt()
  956.         self.set_debugger_indicator()
  957.  
  958.     
  959.     def beginexecuting(self):
  960.         '''Helper for ModifiedInterpreter'''
  961.         self.resetoutput()
  962.         self.executing = 1
  963.  
  964.     
  965.     def endexecuting(self):
  966.         '''Helper for ModifiedInterpreter'''
  967.         self.executing = 0
  968.         self.canceled = 0
  969.         self.showprompt()
  970.  
  971.     
  972.     def close(self):
  973.         '''Extend EditorWindow.close()'''
  974.         if self.executing:
  975.             response = tkMessageBox.askokcancel('Kill?', 'The program is still running!\n Do you want to kill it?', default = 'ok', parent = self.text)
  976.             if response == False:
  977.                 return 'cancel'
  978.             
  979.         
  980.         if self.reading:
  981.             self.top.quit()
  982.         
  983.         self.canceled = True
  984.         self.closing = True
  985.         self.text.after(2 * self.pollinterval, self.close2)
  986.  
  987.     
  988.     def close2(self):
  989.         return EditorWindow.close(self)
  990.  
  991.     
  992.     def _close(self):
  993.         '''Extend EditorWindow._close(), shut down debugger and execution server'''
  994.         self.close_debugger()
  995.         if use_subprocess:
  996.             self.interp.kill_subprocess()
  997.         
  998.         sys.stdout = self.save_stdout
  999.         sys.stderr = self.save_stderr
  1000.         sys.stdin = self.save_stdin
  1001.         self.interp = None
  1002.         self.console = None
  1003.         self.flist.pyshell = None
  1004.         self.history = None
  1005.         EditorWindow._close(self)
  1006.  
  1007.     
  1008.     def ispythonsource(self, filename):
  1009.         '''Override EditorWindow method: never remove the colorizer'''
  1010.         return True
  1011.  
  1012.     
  1013.     def short_title(self):
  1014.         return self.shell_title
  1015.  
  1016.     COPYRIGHT = 'Type "copyright", "credits" or "license()" for more information.'
  1017.     firewallmessage = "\n    ****************************************************************\n    Personal firewall software may warn about the connection IDLE\n    makes to its subprocess using this computer's internal loopback\n    interface.  This connection is not visible on any external\n    interface and no data is sent to or received from the Internet.\n    ****************************************************************\n    "
  1018.     
  1019.     def begin(self):
  1020.         self.resetoutput()
  1021.         if use_subprocess:
  1022.             nosub = ''
  1023.             client = self.interp.start_subprocess()
  1024.             if not client:
  1025.                 self.close()
  1026.                 return False
  1027.             
  1028.         else:
  1029.             nosub = '==== No Subprocess ===='
  1030.         self.write('Python %s on %s\n%s\n%s\nIDLE %s      %s\n' % (sys.version, sys.platform, self.COPYRIGHT, self.firewallmessage, idlever.IDLE_VERSION, nosub))
  1031.         self.showprompt()
  1032.         import Tkinter as Tkinter
  1033.         Tkinter._default_root = None
  1034.         return True
  1035.  
  1036.     
  1037.     def readline(self):
  1038.         save = self.reading
  1039.         
  1040.         try:
  1041.             self.reading = 1
  1042.             self.top.mainloop()
  1043.         finally:
  1044.             self.reading = save
  1045.  
  1046.         line = self.text.get('iomark', 'end-1c')
  1047.         if len(line) == 0:
  1048.             line = '\n'
  1049.         
  1050.         if isinstance(line, unicode):
  1051.             import IOBinding
  1052.             
  1053.             try:
  1054.                 line = line.encode(IOBinding.encoding)
  1055.             except UnicodeError:
  1056.                 pass
  1057.             except:
  1058.                 None<EXCEPTION MATCH>UnicodeError
  1059.             
  1060.  
  1061.         None<EXCEPTION MATCH>UnicodeError
  1062.         self.resetoutput()
  1063.         if self.canceled:
  1064.             self.canceled = 0
  1065.             if not use_subprocess:
  1066.                 raise KeyboardInterrupt
  1067.             
  1068.         
  1069.         if self.endoffile:
  1070.             self.endoffile = 0
  1071.             line = ''
  1072.         
  1073.         return line
  1074.  
  1075.     
  1076.     def isatty(self):
  1077.         return True
  1078.  
  1079.     
  1080.     def cancel_callback(self, event = None):
  1081.         
  1082.         try:
  1083.             if self.text.compare('sel.first', '!=', 'sel.last'):
  1084.                 return None
  1085.         except:
  1086.             pass
  1087.  
  1088.         if not self.executing or self.reading:
  1089.             self.resetoutput()
  1090.             self.interp.write('KeyboardInterrupt\n')
  1091.             self.showprompt()
  1092.             return 'break'
  1093.         
  1094.         self.endoffile = 0
  1095.         self.canceled = 1
  1096.         if self.executing and self.interp.rpcclt:
  1097.             if self.interp.getdebugger():
  1098.                 self.interp.restart_subprocess()
  1099.             else:
  1100.                 self.interp.interrupt_subprocess()
  1101.         
  1102.         if self.reading:
  1103.             self.top.quit()
  1104.         
  1105.         return 'break'
  1106.  
  1107.     
  1108.     def eof_callback(self, event):
  1109.         if self.executing and not (self.reading):
  1110.             return None
  1111.         
  1112.         if not self.text.compare('iomark', '==', 'insert') and self.text.compare('insert', '==', 'end-1c'):
  1113.             return None
  1114.         
  1115.         if not self.executing:
  1116.             self.resetoutput()
  1117.             self.close()
  1118.         else:
  1119.             self.canceled = 0
  1120.             self.endoffile = 1
  1121.             self.top.quit()
  1122.         return 'break'
  1123.  
  1124.     
  1125.     def home_callback(self, event):
  1126.         if event.state != 0 and event.keysym == 'Home':
  1127.             return None
  1128.         
  1129.         if self.text.compare('iomark', '<=', 'insert') and self.text.compare('insert linestart', '<=', 'iomark'):
  1130.             self.text.mark_set('insert', 'iomark')
  1131.             self.text.tag_remove('sel', '1.0', 'end')
  1132.             self.text.see('insert')
  1133.             return 'break'
  1134.         
  1135.  
  1136.     
  1137.     def linefeed_callback(self, event):
  1138.         if self.reading:
  1139.             self.text.insert('insert', '\n')
  1140.             self.text.see('insert')
  1141.         else:
  1142.             self.newline_and_indent_event(event)
  1143.         return 'break'
  1144.  
  1145.     
  1146.     def enter_callback(self, event):
  1147.         if self.executing and not (self.reading):
  1148.             return None
  1149.         
  1150.         
  1151.         try:
  1152.             sel = self.text.get('sel.first', 'sel.last')
  1153.             if sel:
  1154.                 if self.text.compare('sel.last', '<=', 'iomark'):
  1155.                     self.recall(sel, event)
  1156.                     return 'break'
  1157.                 
  1158.         except:
  1159.             pass
  1160.  
  1161.         if self.text.compare('insert', '<', 'iomark linestart'):
  1162.             prev = self.text.tag_prevrange('stdin', 'insert')
  1163.             if prev and self.text.compare('insert', '<', prev[1]):
  1164.                 self.recall(self.text.get(prev[0], prev[1]), event)
  1165.                 return 'break'
  1166.             
  1167.             next = self.text.tag_nextrange('stdin', 'insert')
  1168.             if next and self.text.compare('insert lineend', '>=', next[0]):
  1169.                 self.recall(self.text.get(next[0], next[1]), event)
  1170.                 return 'break'
  1171.             
  1172.             indices = self.text.tag_nextrange('console', 'insert linestart')
  1173.             if indices and self.text.compare(indices[0], '<=', 'insert linestart'):
  1174.                 self.recall(self.text.get(indices[1], 'insert lineend'), event)
  1175.             else:
  1176.                 self.recall(self.text.get('insert linestart', 'insert lineend'), event)
  1177.             return 'break'
  1178.         
  1179.         if self.text.compare('insert', '<', 'iomark'):
  1180.             self.text.mark_set('insert', 'iomark')
  1181.         
  1182.         s = self.text.get('insert', 'end-1c')
  1183.         if s and not s.strip():
  1184.             self.text.delete('insert', 'end-1c')
  1185.         
  1186.         if self.text.compare('insert', '<', 'end-1c linestart'):
  1187.             self.newline_and_indent_event(event)
  1188.             return 'break'
  1189.         
  1190.         self.text.mark_set('insert', 'end-1c')
  1191.         if self.reading:
  1192.             self.text.insert('insert', '\n')
  1193.             self.text.see('insert')
  1194.         else:
  1195.             self.newline_and_indent_event(event)
  1196.         self.text.tag_add('stdin', 'iomark', 'end-1c')
  1197.         self.text.update_idletasks()
  1198.         if self.reading:
  1199.             self.top.quit()
  1200.         else:
  1201.             self.runit()
  1202.         return 'break'
  1203.  
  1204.     
  1205.     def recall(self, s, event):
  1206.         s = re.sub('^\\s*\\n', '', s)
  1207.         s = re.sub('\\n\\s*$', '', s)
  1208.         lines = s.split('\n')
  1209.         self.text.undo_block_start()
  1210.         
  1211.         try:
  1212.             self.text.tag_remove('sel', '1.0', 'end')
  1213.             self.text.mark_set('insert', 'end-1c')
  1214.             prefix = self.text.get('insert linestart', 'insert')
  1215.             if prefix.rstrip().endswith(':'):
  1216.                 self.newline_and_indent_event(event)
  1217.                 prefix = self.text.get('insert linestart', 'insert')
  1218.             
  1219.             self.text.insert('insert', lines[0].strip())
  1220.             if len(lines) > 1:
  1221.                 orig_base_indent = re.search('^([ \\t]*)', lines[0]).group(0)
  1222.                 new_base_indent = re.search('^([ \\t]*)', prefix).group(0)
  1223.                 for line in lines[1:]:
  1224.                     if line.startswith(orig_base_indent):
  1225.                         line = new_base_indent + line[len(orig_base_indent):]
  1226.                     
  1227.                     self.text.insert('insert', '\n' + line.rstrip())
  1228.                 
  1229.         finally:
  1230.             self.text.see('insert')
  1231.             self.text.undo_block_stop()
  1232.  
  1233.  
  1234.     
  1235.     def runit(self):
  1236.         line = self.text.get('iomark', 'end-1c')
  1237.         i = len(line)
  1238.         while i > 0 and line[i - 1] in ' \t':
  1239.             i = i - 1
  1240.         if i > 0 and line[i - 1] == '\n':
  1241.             i = i - 1
  1242.         
  1243.         while i > 0 and line[i - 1] in ' \t':
  1244.             i = i - 1
  1245.         line = line[:i]
  1246.         more = self.interp.runsource(line)
  1247.  
  1248.     
  1249.     def open_stack_viewer(self, event = None):
  1250.         if self.interp.rpcclt:
  1251.             return self.interp.remote_stack_viewer()
  1252.         
  1253.         
  1254.         try:
  1255.             sys.last_traceback
  1256.         except:
  1257.             tkMessageBox.showerror('No stack trace', 'There is no stack trace yet.\n(sys.last_traceback is not defined)', master = self.text)
  1258.             return None
  1259.  
  1260.         StackBrowser = StackBrowser
  1261.         import StackViewer
  1262.         sv = StackBrowser(self.root, self.flist)
  1263.  
  1264.     
  1265.     def view_restart_mark(self, event = None):
  1266.         self.text.see('iomark')
  1267.         self.text.see('restart')
  1268.  
  1269.     
  1270.     def restart_shell(self, event = None):
  1271.         self.interp.restart_subprocess()
  1272.  
  1273.     
  1274.     def showprompt(self):
  1275.         self.resetoutput()
  1276.         
  1277.         try:
  1278.             s = str(sys.ps1)
  1279.         except:
  1280.             s = ''
  1281.  
  1282.         self.console.write(s)
  1283.         self.text.mark_set('insert', 'end-1c')
  1284.         self.set_line_and_column()
  1285.         self.io.reset_undo()
  1286.  
  1287.     
  1288.     def resetoutput(self):
  1289.         source = self.text.get('iomark', 'end-1c')
  1290.         if self.history:
  1291.             self.history.history_store(source)
  1292.         
  1293.         if self.text.get('end-2c') != '\n':
  1294.             self.text.insert('end-1c', '\n')
  1295.         
  1296.         self.text.mark_set('iomark', 'end-1c')
  1297.         self.set_line_and_column()
  1298.         sys.stdout.softspace = 0
  1299.  
  1300.     
  1301.     def write(self, s, tags = ()):
  1302.         
  1303.         try:
  1304.             self.text.mark_gravity('iomark', 'right')
  1305.             OutputWindow.write(self, s, tags, 'iomark')
  1306.             self.text.mark_gravity('iomark', 'left')
  1307.         except:
  1308.             pass
  1309.  
  1310.         if self.canceled:
  1311.             self.canceled = 0
  1312.             if not use_subprocess:
  1313.                 raise KeyboardInterrupt
  1314.             
  1315.         
  1316.  
  1317.  
  1318.  
  1319. class PseudoFile(object):
  1320.     
  1321.     def __init__(self, shell, tags, encoding = None):
  1322.         self.shell = shell
  1323.         self.tags = tags
  1324.         self.softspace = 0
  1325.         self.encoding = encoding
  1326.  
  1327.     
  1328.     def write(self, s):
  1329.         self.shell.write(s, self.tags)
  1330.  
  1331.     
  1332.     def writelines(self, l):
  1333.         map(self.write, l)
  1334.  
  1335.     
  1336.     def flush(self):
  1337.         pass
  1338.  
  1339.     
  1340.     def isatty(self):
  1341.         return True
  1342.  
  1343.  
  1344. usage_msg = '\nUSAGE: idle  [-deins] [-t title] [file]*\n       idle  [-dns] [-t title] (-c cmd | -r file) [arg]*\n       idle  [-dns] [-t title] - [arg]*\n\n  -h         print this help message and exit\n  -n         run IDLE without a subprocess (see Help/IDLE Help for details)\n\nThe following options will override the IDLE \'settings\' configuration:\n\n  -e         open an edit window\n  -i         open a shell window\n\nThe following options imply -i and will open a shell:\n\n  -c cmd     run the command in a shell, or\n  -r file    run script from file\n\n  -d         enable the debugger\n  -s         run $IDLESTARTUP or $PYTHONSTARTUP before anything else\n  -t title   set title of shell window\n\nA default edit window will be bypassed when -c, -r, or - are used.\n\n[arg]* are passed to the command (-c) or script (-r) in sys.argv[1:].\n\nExamples:\n\nidle\n        Open an edit window or shell depending on IDLE\'s configuration.\n\nidle foo.py foobar.py\n        Edit the files, also open a shell if configured to start with shell.\n\nidle -est "Baz" foo.py\n        Run $IDLESTARTUP or $PYTHONSTARTUP, edit foo.py, and open a shell\n        window with the title "Baz".\n\nidle -c "import sys; print sys.argv" "foo"\n        Open a shell window and run the command, passing "-c" in sys.argv[0]\n        and "foo" in sys.argv[1].\n\nidle -d -s -r foo.py "Hello World"\n        Open a shell window, run a startup script, enable the debugger, and\n        run foo.py, passing "foo.py" in sys.argv[0] and "Hello World" in\n        sys.argv[1].\n\necho "import sys; print sys.argv" | idle - "foobar"\n        Open a shell window, run the script piped in, passing \'\' in sys.argv[0]\n        and "foobar" in sys.argv[1].\n'
  1345.  
  1346. def main():
  1347.     global use_subprocess, root, flist
  1348.     use_subprocess = True
  1349.     enable_shell = False
  1350.     enable_edit = False
  1351.     debug = False
  1352.     cmd = None
  1353.     script = None
  1354.     startup = False
  1355.     
  1356.     try:
  1357.         (opts, args) = getopt.getopt(sys.argv[1:], 'c:deihnr:st:')
  1358.     except getopt.error:
  1359.         msg = None
  1360.         sys.stderr.write('Error: %s\n' % str(msg))
  1361.         sys.stderr.write(usage_msg)
  1362.         sys.exit(2)
  1363.  
  1364.     for o, a in opts:
  1365.         if o == '-c':
  1366.             cmd = a
  1367.             enable_shell = True
  1368.         
  1369.         if o == '-d':
  1370.             debug = True
  1371.             enable_shell = True
  1372.         
  1373.         if o == '-e':
  1374.             enable_edit = True
  1375.         
  1376.         if o == '-h':
  1377.             sys.stdout.write(usage_msg)
  1378.             sys.exit()
  1379.         
  1380.         if o == '-i':
  1381.             enable_shell = True
  1382.         
  1383.         if o == '-n':
  1384.             use_subprocess = False
  1385.         
  1386.         if o == '-r':
  1387.             script = a
  1388.             if os.path.isfile(script):
  1389.                 pass
  1390.             else:
  1391.                 print 'No script file: ', script
  1392.                 sys.exit()
  1393.             enable_shell = True
  1394.         
  1395.         if o == '-s':
  1396.             startup = True
  1397.             enable_shell = True
  1398.         
  1399.         if o == '-t':
  1400.             PyShell.shell_title = a
  1401.             enable_shell = True
  1402.             continue
  1403.     
  1404.     if args and args[0] == '-':
  1405.         cmd = sys.stdin.read()
  1406.         enable_shell = True
  1407.     
  1408.     for i in range(len(sys.path)):
  1409.         sys.path[i] = os.path.abspath(sys.path[i])
  1410.     
  1411.     if args and args[0] == '-':
  1412.         sys.argv = [
  1413.             ''] + args[1:]
  1414.     elif cmd:
  1415.         sys.argv = [
  1416.             '-c'] + args
  1417.     elif script:
  1418.         sys.argv = [
  1419.             script] + args
  1420.     elif args:
  1421.         enable_edit = True
  1422.         pathx = []
  1423.         for filename in args:
  1424.             pathx.append(os.path.dirname(filename))
  1425.         
  1426.         for dir in pathx:
  1427.             dir = os.path.abspath(dir)
  1428.             if dir not in sys.path:
  1429.                 sys.path.insert(0, dir)
  1430.                 continue
  1431.         
  1432.     else:
  1433.         dir = os.getcwd()
  1434.         if dir not in sys.path:
  1435.             sys.path.insert(0, dir)
  1436.         
  1437.     edit_start = idleConf.GetOption('main', 'General', 'editor-on-startup', type = 'bool')
  1438.     if not enable_edit:
  1439.         pass
  1440.     enable_edit = edit_start
  1441.     if not enable_shell:
  1442.         pass
  1443.     enable_shell = not edit_start
  1444.     root = Tk(className = 'Idle')
  1445.     fixwordbreaks(root)
  1446.     root.withdraw()
  1447.     flist = PyShellFileList(root)
  1448.     macosxSupport.setupApp(root, flist)
  1449.     if enable_edit:
  1450.         if not cmd or script:
  1451.             for filename in args:
  1452.                 flist.open(filename)
  1453.             
  1454.             if not args:
  1455.                 flist.new()
  1456.             
  1457.         
  1458.     
  1459.     if enable_shell:
  1460.         shell = flist.open_shell()
  1461.         if not shell:
  1462.             return None
  1463.         
  1464.         if macosxSupport.runningAsOSXApp() and flist.dict:
  1465.             shell.top.lower()
  1466.         
  1467.     
  1468.     shell = flist.pyshell
  1469.     if debug:
  1470.         shell.open_debugger()
  1471.     
  1472.     if startup:
  1473.         if not os.environ.get('IDLESTARTUP'):
  1474.             pass
  1475.         filename = os.environ.get('PYTHONSTARTUP')
  1476.         if filename and os.path.isfile(filename):
  1477.             shell.interp.execfile(filename)
  1478.         
  1479.     
  1480.     if shell or cmd or script:
  1481.         shell.interp.runcommand('if 1:\n            import sys as _sys\n            _sys.argv = %r\n            del _sys\n            \n' % (sys.argv,))
  1482.         if cmd:
  1483.             shell.interp.execsource(cmd)
  1484.         elif script:
  1485.             shell.interp.prepend_syspath(script)
  1486.             shell.interp.execfile(script)
  1487.         
  1488.     
  1489.     root.mainloop()
  1490.     root.destroy()
  1491.  
  1492. if __name__ == '__main__':
  1493.     sys.modules['PyShell'] = sys.modules['__main__']
  1494.     main()
  1495.  
  1496.